package com.trip.service;

import com.trip.dao.tables.records.PlaceAndExpRecord;
import com.trip.dao.tables.records.UserCollectionRecord;
import com.trip.exception.ServiceException;
import com.trip.vo.CollectionIndexItemVo;
import com.trip.vo.CollectionIndexVo;
import com.trip.vo.PlaceAndExperienceListItemVo;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import static com.trip.dao.Tables.PLACE_AND_EXP;
import static com.trip.dao.Tables.USER_COLLECTION;
import static com.trip.dao.Tables.USER_RELATED;

/**
 * Created by hc24 on 2017/10/4.
 */
@Service
@Transactional
public class CollectionService {

    @Autowired
    private DSLContext dslContext;

    @Autowired
    private PlaceAndExperienceService placeAndExperienceService;

    @Transactional(readOnly = true)
    public List<PlaceAndExperienceListItemVo> queryList(Integer type,Integer userId){
         return dslContext.select(PLACE_AND_EXP.fields()).select(USER_RELATED.NOTE.as("notes")).from(USER_COLLECTION)
                .leftJoin(PLACE_AND_EXP).on(PLACE_AND_EXP.ID.eq(USER_COLLECTION.PAE_ID))
                 .leftJoin(USER_RELATED).on(USER_RELATED.PAEID.eq(PLACE_AND_EXP.ID)).and(USER_RELATED.USERID.eq(userId))
                .where(USER_COLLECTION.USER_ID.eq(userId),USER_COLLECTION.PAE_TYPE.eq(type))
                .orderBy(USER_COLLECTION.COLLECTED_TIME.desc())
                .fetchStream().map(e->e.into(PlaceAndExperienceListItemVo.class)).peek(e->e.setCollected(true)).collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    public CollectionIndexVo queryIndex(Integer type,Integer userId){
        CollectionIndexVo indexVo=new CollectionIndexVo();
        List<CollectionIndexItemVo> itemList= dslContext.select(USER_COLLECTION.PAE_ID,PLACE_AND_EXP.COVER).from(USER_COLLECTION)
                .leftJoin(PLACE_AND_EXP).on(USER_COLLECTION.PAE_ID.eq(PLACE_AND_EXP.ID))
                .where(USER_COLLECTION.USER_ID.eq(userId),USER_COLLECTION.PAE_TYPE.eq(type))
                .orderBy(USER_COLLECTION.COLLECTED_TIME.desc())
                .limit(3)
                .fetchInto(CollectionIndexItemVo.class);

        Integer count= dslContext.selectCount().from(USER_COLLECTION)
                .where(USER_COLLECTION.USER_ID.eq(userId),USER_COLLECTION.PAE_TYPE.eq(type))
                .fetch().get(0).value1();

        indexVo.setCount(count);
        indexVo.setItemList(itemList);

        return indexVo;
    }

    public void delete(String paeId,Integer userId){
        //only can delete self collection
        dslContext.delete(USER_COLLECTION)
                .where(USER_COLLECTION.PAE_ID.eq(paeId),USER_COLLECTION.USER_ID.eq(userId))
                .execute();

    }

    public void create(Integer userId,String paeId,Integer type){
        if(dslContext.selectCount().from(USER_COLLECTION)
                .where(USER_COLLECTION.PAE_ID.eq(paeId),USER_COLLECTION.USER_ID.eq(userId))
                .fetchOne().value1()>0)
            throw new ServiceException("You have collected");

        UserCollectionRecord ucr=dslContext.newRecord(USER_COLLECTION);
        ucr.setUserId(userId);
        ucr.setPaeId(paeId);
        ucr.setCollectedTime(LocalDateTime.now());

        if(type==null){
            PlaceAndExpRecord placeAndExpRecord= placeAndExperienceService.query(paeId);
            if(placeAndExpRecord==null)
                throw new ServiceException("Place or Experience is not exists.");
            ucr.setPaeType(placeAndExpRecord.getType().intValue());
        }else{
            ucr.setPaeType(type);
        }

        ucr.insert();
    }

}
